Ruby 日記 50日目: extend self で自身のメソッドを自身の特異メソッドに追加する
次のプログラムでmethod_1が呼び出せる組み合わせを選んでください
code:rb
module Parent
def method_1
__method__
end
end
module Child
# ここに挿入する選択肢を選んでください。
end
p Child::method_1
選択肢:
code:sh
include Parent
include self
code:sh
extend self
include Parent
code:sh
include Parent
extend self
code:sh
extend Parent
解説:
インクルードとは、指定されたモジュールの定義 (メソッド、定数) を引き継ぐことです。
だね
include self をしたら無限ループしちゃうんじゃないかな
なので、選択肢1は
code:sh
# ruby gold/ex50/choice01.rb
gold/ex50/choice01.rb:9:in `append_features': cyclic include detected (ArgumentError)
from gold/ex50/choice01.rb:9:in `include'
from gold/ex50/choice01.rb:9:in `<module:Child>'
from gold/ex50/choice01.rb:7:in `<main>'
こうなるね
引数で指定したモジュールのインスタンスメソッドを self の特異 メソッドとして追加します。
extend self で自身のメソッドを自身の特異メソッドとして追加することもできるのね
例えばこの場合は
code:sample01.rb
module A
def foo
p 'foo'
end
end
A::foo
NoMethodErrorになるけど、
code:sh
# ruby gold/ex50/sample01.rb
gold/ex50/sample01.rb:7:in <main>': undefined method foo' for A:Module (NoMethodError)
この場合は
code:sample02.rb
module A
extend self
def foo
p 'foo'
end
end
A::foo
エラーにならない
code:sh
# ruby gold/ex50/sample02.rb
"foo"
選択肢2はParentモジュールをincludeする前にextend selfしているので、ParentモジュールのメソッドはChildモジュールの特異メソッドとして追加されることはなく、NoMethodErrorになる
code:sh
# ruby gold/ex50/choice02.rb
gold/ex50/choice02.rb:12:in <main>': undefined method method_1' for Child:Module (NoMethodError)
選択肢3はParentモジュールをincludeした後にextend selfしているので、ParentモジュールのメソッドはChildモジュールの特異メソッドとして追加される。
code:sh
# ruby gold/ex50/choice03.rb
:method_1
選択肢4はParentモジュールをextendしているので、ParentモジュールのメソッドはChildモジュールの特異メソッドとして追加される。
code:sh
# ruby gold/ex50/choice04.rb
:method_1
したがって、正解は選択肢3と選択肢4だね〜。